﻿using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Cfg;

namespace StudentsDB
{
    public class HibernateTemplate
    {
        private static ISessionFactory _sessionFactory;
        private static readonly Object Monitor = new Object();

        public static ISessionFactory GetSessionFactory()
        {
            if (_sessionFactory == null)
            {
                lock (Monitor)
                {
                    if (_sessionFactory == null)
                    {
                        Configuration conf = new Configuration();

                        conf.AddAssembly("StudentsDB");

                        _sessionFactory = conf.BuildSessionFactory();
                    }
                }
            }
            return _sessionFactory;
        }


        public static ISession GetSession()
        {
            return GetSessionFactory().OpenSession();
        }

        public static IList<T> FindAll<T>() where T : DomainObject
        {
            return new List<T>(GetSession().CreateCriteria(typeof(T)).List().Cast<T>());
        }

        public static T DoInTransaction<T>(Func<ISession, T> action)
        {
            ISession session = GetSession();
            ITransaction tx = session.BeginTransaction();
            T result;
            try
            {
                result = action.Invoke(session);
            }
            catch (Exception e)
            {
                tx.Rollback();
                throw e;
            }
            tx.Commit();
            return result;
        }

        public static void DoInTransaction(Action<ISession> action)
        {
            DoInTransaction((session) =>
            {
                action.Invoke(session);
                return 0;
            });
        }
    }
}
